﻿using System;
using System.Collections.Generic;
using System.Linq;
using Xlit.Example.Business.Models;
using Xlit.Project.Data;
using Xlit.Project.Entity.Domain;
using Xlit.Project.Model.SysAccountDto;
using Xlit.Project.Mvc.Models;
using Xlit.Project.Service;
using Xlit.Standard.Data;
using Xlit.Utility;

namespace Xlit.Example.Business.Services
{
    /// <summary>
    ///  系统账户
    /// </summary>
    public class SysAccountService : AppServiceBase
    {
        public IRepository<Sys_Menu, int> _SysMenuRepository { get; set; }
        public IRepository<Sys_Account, int> _SysAccountRepository { get; set; }
        public IRepository<Sys_AccountRole, int> _SysAccountRoleRepository { get; set; }
        public IRepository<Sys_RoleMenu, int> _SysRoleMenuRepository { get; set; }

        /// <summary>
        ///  用户登录判定
        /// </summary>
        /// <param name="credential">登录凭据</param>
        /// <param name="password">口令明文</param>
        /// <returns></returns>
        public Sys_Account Login(string credential, string password)
        {
            // 用户名/手机号验证
            var user = _SysAccountRepository.First(d => d.TelPhone == credential || d.Username == credential);

            if (user == null)
            {
                throw new ApplicationException("账户或密码错误");
            }

            // 账户状态验证
            if (!user.IsActive)
            {
                throw new ApplicationException("该账户已被锁定, 请联系管理员");
            }

            // 密码验证
            if (user.Password != StringUtil.MD5Encrypt(password))
            {
                user.IsActive = !(++user.TryCount >= 5);
                _SysAccountRepository.Update(user);
                throw new ApplicationException($"密码错误, 尝试次数过多将会锁定账户");
            }

            user.TryCount = 0;
            _SysAccountRepository.Update(user);

            return user;
        }

        /// <summary>
        ///  根据id获取用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Sys_Account Get(int id)
        {
            return _SysAccountRepository.GetEntity(id);
        }

        /// <summary>
        ///  获取系统用户集
        /// </summary>
        /// <returns></returns>
        public QueryOutput<Sys_Account> Get(QueryInput input)
        {
            // Data
            var sysAccountList = _SysAccountRepository.Entities;

            // Filter

            // Sort

            // Paging
            sysAccountList = sysAccountList
               .Skip(input.CurrentPage * input.PageSize)
               .Take(input.PageSize);

            // Select(联合查询)

            // 输出
            var output = new QueryOutput<Sys_Account>
            {
                Total = sysAccountList.Count(),
                List = sysAccountList.ToList(),
                CurrentPage = input.CurrentPage
            };

            return output;
        }

        /// <summary>
        ///  根据用户id获得用户角色列表
        /// </summary>
        /// <param name="userid">用户id</param>
        /// <returns></returns>
        public IEnumerable<int> GetUserRoleList(int userid)
        {
            var userRoleList = _SysAccountRoleRepository
                .GetList(d => d.AccountId == userid);
            return userRoleList.Select(d => d.RoleId);
        }

        /// <summary>
        ///  更新用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [Transactional]
        public virtual void Update(SysAccountVO input)
        {
            var user = _SysAccountRepository.GetEntity(input.Id);

            if (user == null)
            {
                user = new Sys_Account
                {
                    Name = input.Name,
                    Username = input.Username,
                    TelPhone = input.TelPhone,
                    Email = input.Email,
                    IsAdmin = false,
                    IsActive = input.IsActive
                };
                _SysAccountRepository.Insert(user);
            }
            else
            {
                user.Name = input.Name;
                user.Username = input.Username;
                user.TelPhone = input.TelPhone;
                user.Email = input.Email;
                user.IsActive = input.IsActive;
                _SysAccountRepository.Update(user);
            }

            _SysAccountRoleRepository.Delete(d => d.AccountId == input.Id);
            var accountRole = input.Roles
                .Select(s => new Sys_AccountRole
                {
                    AccountId = input.Id,
                    RoleId = s
                });
            _SysAccountRoleRepository.Insert(accountRole);
        }

        /// <summary>
        ///  更新用户的密码
        /// </summary>
        /// <param name="userid">账号id</param>
        /// <param name="input">更新内容</param>
        /// <returns></returns>
        [Transactional]
        public int UpdatePassword(int userid, UpdatePasswordInput input)
        {
            var user = _SysAccountRepository.GetEntity(userid);
            var password = StringUtil.MD5Encrypt(input.Password);
            if (user == null)
                throw new ApplicationException("找不到该账号信息");
            if (password != user.Password)
                throw new ApplicationException("原密码错误");
            if (input.NewPassword != input.ConfirmPassword)
                throw new ApplicationException("两次密码不相同");
            user.Password = StringUtil.MD5Encrypt(input.NewPassword);
            return _SysAccountRepository.Update(user);
        }

        /// <summary>
        ///  删除系统用户
        /// </summary>
        /// <param name="id">用户id</param>
        /// <returns></returns>
        public int Delete(int id)
        {
            return _SysAccountRepository.Delete(id);
        }

        /// <summary>
        ///  获取用户菜单集
        /// </summary>
        /// <param name="id">用户id</param>
        /// <returns></returns>
        public IList<Sys_Menu> GetUserMenu(int id)
        {
            // 用户拥有的角色
            var userRole = _SysAccountRoleRepository
                .GetList(d => d.AccountId == id)
                .Select(d => d.RoleId);

            // 用户角色对应的菜单
            var userMenu = userRole
                .Join(
                    _SysRoleMenuRepository.Entities,
                    r => r,
                    m => m.RoleId,
                    (r, m) => m.MenuId)
                .Distinct()
                .ToList();

            // 获取用户对应菜单
            var list = _SysMenuRepository
                .GetList(d => d.IsVisible);
            return list
                .Join(
                    userMenu,
                    m => m.Id, um => um,
                    (m, um) => m)
                .Where(d => !d.ParentId.HasValue)
                .ToList();
        }

        ///// <summary>
        /////  更新用户账号信息
        ///// </summary>
        ///// <param name="userid">账号id</param>
        ///// <param name="input">更新内容</param>
        ///// <returns></returns>
        //[UnitOfWork]
        //public  Task UpdateUserInfo(int userid, UserInfoUpdateInput input)
        //{
        //    var user =  SysAccountRepository.GetEntity(userid);
        //    if (user == null)
        //        throw new ApplicationException("找不到该账号信息");
        //    user.Photo = input.Photo;
        //    user.Name = input.Name;
        //    user.TelPhone = input.TelPhone;
        //    user.Email = input.Email;
        //     SysAccountRepository.Update(user);
        //}
    }
}
